import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:convert/convert.dart';
import 'package:dio/dio.dart';
import 'package:encrypt/encrypt.dart';
import 'package:flutter/material.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:videotop/base_model.dart';
import 'package:videotop/myinfo.dart';
import 'package:package_info/package_info.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'jsonbean/init.dart';
import 'jsonbean/login_bean.dart';
import 'jsonbean/matchs.dart';
import 'jsonbean/spacebean.dart';

/// created by hx
///    2021/1/23:15:08

class Util extends BaseModel{

  String appName;
  String packageName;
  String versionName;
  String versionCode;

  String package = '';// 此应用的路径
  int urlTime = 0; // 服务器下发时间

  SharedPreferences spfs;
  int msgCount = 0;

  List<CameraDescription> cameras;

  setMsgCount(int num){
    this.msgCount = num;
    notifyListeners();
  }

  final String baseurl = "http://im.monkeyzoo.top:7041/";
  // static final String baseurl = "http://192.168.0.110:8080/New_Monkey/";

  String privacy_policy = 'http://cdn.monkeyzoo.top/privacy/privacy_monkeyzoo.html';
  String terms_of_service = 'http://cdn.monkeyzoo.top/terms/monkeyzoo.html';

  final String upurl_video = 'http://cdn.yuemoim.com/Monkeyzoo/';
  final String upurl_jianhuang = 'https://cdn-oversea.oss-us-west-1.aliyuncs.com/Monkeyzoo/image/';
  final String appneame = 'Monkeyzoo/';

  setPageInfo(PackageInfo packageInfo){
    appName = packageInfo.appName;
    packageName = packageInfo.packageName;
    versionName = packageInfo.version;
    versionCode = packageInfo.buildNumber;
    notifyListeners();
  }

  Future<void> init() async{
    spfs = await SharedPreferences.getInstance();
    if(Platform.isIOS){
      Directory appDocDir = await getLibraryDirectory();
      String dir = appDocDir.path;
      package = '${dir}/Caches/';
    }
    var data = FormData.fromMap({
      'code':'US',
      'sex':1
    });
    BaseOptions options = new BaseOptions(responseType: ResponseType.plain);
    Dio dio = new Dio(options);
    var response = await dio.post('${baseurl}init.do',data: data);
    var result = json.decode(response.data);
    Init initdata = Init.fromJson(result);
    urlTime = initdata.time;
  }

  ///登录
  Future<LoginBean> login(int type,String logid,String psd) async {
    BaseOptions options = new BaseOptions(responseType: ResponseType.plain);
    var data = FormData.fromMap(
        {'type': type, 'logid':logid, 'psd':psd}
    );
    Dio dio = new Dio(options);
    var response = await dio.post('${baseurl}login.do', data: data);
    Map json2 = json.decode(response.data);
    return LoginBean.fromJson(json2);
  }

  ///注册
  Future<LoginBean> reg(int type,String logid,String psd,String nickname,int sex,) async {
    BaseOptions options = new BaseOptions(responseType: ResponseType.plain);
    var data = FormData.fromMap(
        {
          'type': type,
          'logid': logid,
          'nickname': nickname,
          'sex': sex,
          'psd': psd,
        }
    );

    Dio dio = new Dio(options);
    var response = await dio.post('${baseurl}reg.do', data: data);
    Map json2 = json.decode(response.data.toString());
    LoginBean login = LoginBean.fromJson(json2);

    return login;
  }

  ///聊天头像昵称
  Future<Map> getBasicInfo(int uid) async {
    BaseOptions options = new BaseOptions(responseType: ResponseType.json);
    var data = FormData.fromMap({'uid': uid});
    Dio dio = new Dio(options);
    var response = await dio.post(baseurl+'getBasicInfo.do', data: data);
    Map map = response.data;
    return map;
  }

  ///修改金币/vip
  Future<int> setGold(int count,int type,int uid) async {
    BaseOptions options = new BaseOptions(responseType: ResponseType.json);
    var timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    String sign = await getSign({'count': count,'uid':uid,'type':type,'timestamp':timestamp});
    var signd = await encodePassword(sign);
    var data = FormData.fromMap({'count': count,'uid':uid,'type':type,'sign':signd,'timestamp':timestamp});
    Dio dio = new Dio(options);
    var response = await dio.post(baseurl+'ua.do', data: data);
    return response.data;
  }

  ///获取签名
  static Future<String> getSign(Map parameter) async{
    /// 存储所有key
    List<String> allKeys = [];
    parameter.forEach((key,value){
      allKeys.add(key + '=$value&');
    });
    /// key排序
    allKeys.sort((obj1,obj2){
      return obj1.compareTo(obj2);
    });
    /// 数组转string
    String pairsString = allKeys.join("");
    String sign = pairsString.substring(0,pairsString.length-1);
    /// hash
    var signString = await generateMd5(sign);
//    String signString = md5.convert(utf8.encode(sign)).toString().toUpperCase();  //直接写也可以
    return signString.toUpperCase();
  }

  /// md5 加密
  static Future<String> generateMd5(String data) async{
    var content = new Utf8Encoder().convert(data);
    var digest = md5.convert(content);
    // 这里其实就是 digest.toString()
    return hex.encode(digest.bytes);
  }

  /// 公钥加密工具
  static Future<String> encodePassword(String src) async {
    String public = '-----BEGIN PUBLIC KEY-----\n'
        'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIfLydTxsaI/NTBSyhmWCSr4iEEDO8Wl+IR34amVly5XInYwIFSXv6WG2xLt10PzxVCHjyDWkur2AXAFJsRV8b8CAwEAAQ==\n'
        '-----END PUBLIC KEY-----';
    var publicKey = RSAKeyParser().parse(public);
    final encrypter = Encrypter(RSA(publicKey: publicKey));
    final encrypted = encrypter.encrypt(src).base64;
//    final decrypted = encrypter.decrypt(encrypted);
//    print('decrypted= $decrypted');
    return encrypted;
  }


  ///跳转隐私
  Future<Null> goTerms() async{
    if (await canLaunch(terms_of_service)) {
    await launch(terms_of_service);
    } else {
    throw 'Could not launch $terms_of_service';
    }
  }

  ///是否在视频
  Future<bool> getisvideo(int uid) async{
    BaseOptions options = new BaseOptions(responseType: ResponseType.json);
    var data = FormData.fromMap({'uid':uid});
    Dio dio = new Dio(options);
    var response = await dio.post(baseurl+'isVideoNow.do', data: data);
    if(response.data == 1){
      return true;
    }else{
      return false;
    }
  }

  ///修改视频状态
  Future<bool> setUpdateVideoNow(int uid,int zuid,int status) async{
    BaseOptions options = new BaseOptions(responseType: ResponseType.json);
    var data = FormData.fromMap({'uid':uid, 'zuid':zuid, 'status':status});
    Dio dio = new Dio(options);
    var response = await dio.post(baseurl+'updateVideoNow.do', data: data);
  }

  ///配对过的数据
  Future<List<MatchedUsers>> getMatchData(int page,int uid) async {
    BaseOptions options = new BaseOptions(responseType: ResponseType.plain);
    var data = FormData.fromMap({'page': page, 'uid':uid});
    Dio dio = new Dio(options);
    var response = await dio.post(baseurl+'getMatchedUsers.do', data: data);
    var json2 = json.decode(response.data.toString());
    List<MatchedUsers> newList = new Matcheds.fromJson(json2).list;
    return newList;
  }

  /// 空间
  Future<SpaceUser> getuserinfo(int uid) async {
    BaseOptions options = new BaseOptions(responseType: ResponseType.plain);
    var data = FormData.fromMap({'uid': uid});
    Dio dio = new Dio(options);
    var response = await dio.post('${baseurl}getUserInfo.do', data: data);
    Map json2 = json.decode(response.data.toString());
    return SpaceUser.fromJson(json2);
  }

  /// 关注/取关
  Future<int> getfollow(int status, int cuid,int uid) async {
    try {
      var data =
      FormData.fromMap({'status': status, 'uid': uid, 'cuid': cuid});
      Response response = await Dio().post(baseurl + 'like.do', data: data);
      if (response.toString() == '1') {
        return 1;
      } else {
        return 0;
      }
    } catch (e) {
      print(e);
    }
  }

  ///举报
  Future<int> getreportUser(int suid,int type,String img,String content,int uid) async{
    Response response;
    BaseOptions options = new BaseOptions(responseType: ResponseType.json);
    Dio dio = new Dio(options);
    FormData formData = FormData.fromMap({
      "type": type,
      "img": img,
      "suid": suid,
      "uid": uid,
      "time": DateTime.now().millisecondsSinceEpoch,
    });
    response = await dio.post(baseurl + "reportUser.do", data: formData);
    return response.data;
  }

  /// 上传图片
  Future<int> upimg( String fileName,
      String path) async {
    //构建policy, `expriation`设置该Policy的失效时间，超过这个失效时间之后，就没有办法通过这个policy上传文件了, `content-length-range`设置上传文件的大小限制
    String policyText =
        '{"expiration": "2050-01-01T12:00:00.000Z","conditions": [["content-length-range", 0, 1048576000]]}';
    List<int> policyText_utf8 = utf8.encode(policyText);
    String policy_base64 = base64.encode(policyText_utf8);
    List<int> policy = utf8.encode(policy_base64);

    // 利用OSSAccesskeySecret签名Policy
    List<int> key = utf8.encode('aYMudgrZABDhal3gSgemS436XBBYjW');
    List<int> signature_pre = new Hmac(sha1, key).convert(policy).bytes;
    String signature = base64.encode(signature_pre);

    BaseOptions options = new BaseOptions(responseType: ResponseType.plain);
    Dio dio = new Dio(options);

    // 构建formData数据
    FormData data = new FormData.fromMap({
      'key': fileName,
      'policy': policy_base64,
      'OSSAccessKeyId': 'LTAIMonv6hyqpy8n',
      'success_action_status': '200',
      'signature': signature,
      'file': await MultipartFile.fromFile(path,filename: fileName),
    });
    Response response = await dio.post('https://cdn-oversea.oss-us-west-1.aliyuncs.com', data: data);
    if(response.statusCode == 200){
      return 1;
    }else {
      return 0;
    }
  }

  ///根据日期，返回星座
  String getConstellation(DateTime birthday,BuildContext context) {
    final String capricorn = 'Capricorn'; //Capricorn 摩羯座（12月22日～1月20日）
    final String aquarius = 'Aquarius'; //Aquarius 水瓶座（1月21日～2月19日）
    final String pisces = 'Pisces'; //Pisces 双鱼座（2月20日～3月20日）
    final String aries = 'Aries'; //3月21日～4月20日
    final String taurus = 'Taurus'; //4月21～5月21日
    final String gemini = 'Gemini'; //5月22日～6月21日
    final String cancer = 'Cancer'; //Cancer 巨蟹座（6月22日～7月22日）
    final String leo = 'Leo'; //Leo 狮子座（7月23日～8月23日）
    final String virgo = 'Virgo'; //Virgo 处女座（8月24日～9月23日）
    final String libra = 'Libra'; //Libra 天秤座（9月24日～10月23日）
    final String scorpio = 'Scorpio'; //Scorpio 天蝎座（10月24日～11月22日）
    final String sagittarius = 'Sagittarius'; //Sagittarius 射手座（11月23日～12月21日）

    int month = birthday.month;
    int day = birthday.day;
    String constellation = '';

    switch (month) {
      case DateTime.january:
        constellation = day < 21 ? capricorn : aquarius;
        break;
      case DateTime.february:
        constellation = day < 20 ? aquarius : pisces;
        break;
      case DateTime.march:
        constellation = day < 21 ? pisces : aries;
        break;
      case DateTime.april:
        constellation = day < 21 ? aries : taurus;
        break;
      case DateTime.may:
        constellation = day < 22 ? taurus : gemini;
        break;
      case DateTime.june:
        constellation = day < 22 ? gemini : cancer;
        break;
      case DateTime.july:
        constellation = day < 23 ? cancer : leo;
        break;
      case DateTime.august:
        constellation = day < 24 ? leo : virgo;
        break;
      case DateTime.september:
        constellation = day < 24 ? virgo : libra;
        break;
      case DateTime.october:
        constellation = day < 24 ? libra : scorpio;
        break;
      case DateTime.november:
        constellation = day < 23 ? scorpio : sagittarius;
        break;
      case DateTime.december:
        constellation = day < 22 ? sagittarius : capricorn;
        break;
    }

    return constellation;
  }

  ///计算年龄
  int getAge(DateTime brt){
    int age = 0;
    DateTime dateTime = DateTime.now();
//    if (dateTime.isAfter(brt)) { //出生日期晚于当前时间，无法计算
//      return '出生日期不正確';
//    }
    int yearNow = dateTime.year;  //当前年份
    int monthNow = dateTime.month;  //当前月份
    int dayOfMonthNow = dateTime.day; //当前日期

    int yearBirth = brt.year;
    int monthBirth = brt.month;
    int dayOfMonthBirth = brt.day;
    age = yearNow - yearBirth;   //计算整岁数
    if (monthNow <= monthBirth) {
      if (monthNow == monthBirth) {
        if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
      } else {
        age--;//当前月份在生日之前，年龄减一
      }
    }
    return age;
  }


  ///跳转协议
  Future<Null> goPrivacy() async{
    if (await canLaunch(privacy_policy)) {
      await launch(privacy_policy);
    } else {
      throw 'Could not launch $privacy_policy';
    }
  }

  MethodChannel platform = const MethodChannel("com.lh.monkeyzoo");

  ///登录声网
  Future<void>getNativeLogin() async {
    String result = '';
    try {
      //参数为方法名称
      MyInfo myInfo;
      print('====Util==myInfo=======${myInfo.uid}========');
      result = await platform.invokeMethod("login", myInfo.uid);
      if (result == '0' || result == '8') {
        print('登录成功');
      } else {
        print('登录失败');
        Timer(Duration(seconds: 10), () {
          getNativeLogin();
        });
      }
    } on PlatformException catch (e) {
      print(e.message);
    }
  }

  ///退出声网
  Future<void> getNativeLoginout() async{
    platform.invokeMethod("loginout", 'out');
  }

  ///对方的uid
  Future<bool> getNativeYuid(int uid) async {
    await platform.invokeMethod("yuid", '$uid').then((value){
      if(value == '0'){
        return true;
      }else{
        return false;
      }
    });
    return true;
  }

  ///发送文字
  Future<void> sendTextMessage(String text) async{
    await platform.invokeMethod("send", '$text').then((value){

    });
  }

  ///请求麦克风权限
  Future<bool> requestVoice(BuildContext context) async {
    if (await Permission.microphone.request().isGranted) {
      return true;
    } else {
      return false;
    }
  }

  ///请求相机权限
  Future<bool> requestCamera(BuildContext context) async {
    if (await Permission.camera.request().isGranted) {
      return true;
    } else {
      return false;
    }
  }

  ///等待
  waiting(BuildContext context) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (ctx) {
        return Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),strokeWidth: 2,),
//                  SpinKitRotatingCircle(color: Colors.white,size: 30,),
                ],
              ),
            ],
          ),
        );
      },
    );
  }

  ///Toast消息
  showToast(String msg,{
    Color textColor : Colors.white,
    ToastGravity gravity : ToastGravity.BOTTOM,
    Toast toastLength : Toast.LENGTH_SHORT,
    Color backgroundColor : Colors.black,
    double fontSize : 16.0
  }) {
    Fluttertoast.showToast(
        msg: msg,
        toastLength: toastLength,
        gravity: gravity,
        timeInSecForIosWeb: 1,
        backgroundColor: backgroundColor,
        textColor: textColor,
        fontSize: fontSize
    );
  }
}